const MIN_YEAR = 1891
const MAX_YEAR = 2100
const lunarInfo = [
  [0, 2, 9, 21936], [6, 1, 30, 9656], [0, 2, 17, 9584], [0, 2, 6, 21168], [5, 1, 26, 43344], [0, 2, 13, 59728],
  [0, 2, 2, 27296], [3, 1, 22, 44368], [0, 2, 10, 43856], [8, 1, 30, 19304], [0, 2, 19, 19168], [0, 2, 8, 42352],
  [5, 1, 29, 21096], [0, 2, 16, 53856], [0, 2, 4, 55632], [4, 1, 25, 27304], [0, 2, 13, 22176], [0, 2, 2, 39632],
  [2, 1, 22, 19176], [0, 2, 10, 19168], [6, 1, 30, 42200], [0, 2, 18, 42192], [0, 2, 6, 53840], [5, 1, 26, 54568],
  [0, 2, 14, 46400], [0, 2, 3, 54944], [2, 1, 23, 38608], [0, 2, 11, 38320], [7, 2, 1, 18872], [0, 2, 20, 18800],
  [0, 2, 8, 42160], [5, 1, 28, 45656], [0, 2, 16, 27216], [0, 2, 5, 27968], [4, 1, 24, 44456], [0, 2, 13, 11104],
  [0, 2, 2, 38256], [2, 1, 23, 18808], [0, 2, 10, 18800], [6, 1, 30, 25776], [0, 2, 17, 54432], [0, 2, 6, 59984],
  [5, 1, 26, 27976], [0, 2, 14, 23248], [0, 2, 4, 11104], [3, 1, 24, 37744], [0, 2, 11, 37600], [7, 1, 31, 51560],
  [0, 2, 19, 51536], [0, 2, 8, 54432], [6, 1, 27, 55888], [0, 2, 15, 46416], [0, 2, 5, 22176], [4, 1, 25, 43736],
  [0, 2, 13, 9680], [0, 2, 2, 37584], [2, 1, 22, 51544], [0, 2, 10, 43344], [7, 1, 29, 46248], [0, 2, 17, 27808],
  [0, 2, 6, 46416], [5, 1, 27, 21928], [0, 2, 14, 19872], [0, 2, 3, 42416], [3, 1, 24, 21176], [0, 2, 12, 21168],
  [8, 1, 31, 43344], [0, 2, 18, 59728], [0, 2, 8, 27296], [6, 1, 28, 44368], [0, 2, 15, 43856], [0, 2, 5, 19296],
  [4, 1, 25, 42352], [0, 2, 13, 42352], [0, 2, 2, 21088], [3, 1, 21, 59696], [0, 2, 9, 55632], [7, 1, 30, 23208],
  [0, 2, 17, 22176], [0, 2, 6, 38608], [5, 1, 27, 19176], [0, 2, 15, 19152], [0, 2, 3, 42192], [4, 1, 23, 53864],
  [0, 2, 11, 53840], [8, 1, 31, 54568], [0, 2, 18, 46400], [0, 2, 7, 46752], [6, 1, 28, 38608], [0, 2, 16, 38320],
  [0, 2, 5, 18864], [4, 1, 25, 42168], [0, 2, 13, 42160], [10, 2, 2, 45656], [0, 2, 20, 27216], [0, 2, 9, 27968],
  [6, 1, 29, 44448], [0, 2, 17, 43872], [0, 2, 6, 38256], [5, 1, 27, 18808], [0, 2, 15, 18800], [0, 2, 4, 25776],
  [3, 1, 23, 27216], [0, 2, 10, 59984], [8, 1, 31, 27432], [0, 2, 19, 23232], [0, 2, 7, 43872], [5, 1, 28, 37736],
  [0, 2, 16, 37600], [0, 2, 5, 51552], [4, 1, 24, 54440], [0, 2, 12, 54432], [0, 2, 1, 55888], [2, 1, 22, 23208],
  [0, 2, 9, 22176], [7, 1, 29, 43736], [0, 2, 18, 9680], [0, 2, 7, 37584], [5, 1, 26, 51544], [0, 2, 14, 43344],
  [0, 2, 3, 46240], [4, 1, 23, 46416], [0, 2, 10, 44368], [9, 1, 31, 21928], [0, 2, 19, 19360], [0, 2, 8, 42416],
  [6, 1, 28, 21176], [0, 2, 16, 21168], [0, 2, 5, 43312], [4, 1, 25, 29864], [0, 2, 12, 27296], [0, 2, 1, 44368],
  [2, 1, 22, 19880], [0, 2, 10, 19296], [6, 1, 29, 42352], [0, 2, 17, 42208], [0, 2, 6, 53856], [5, 1, 26, 59696],
  [0, 2, 13, 54576], [0, 2, 3, 23200], [3, 1, 23, 27472], [0, 2, 11, 38608], [11, 1, 31, 19176], [0, 2, 19, 19152],
  [0, 2, 8, 42192], [6, 1, 28, 53848], [0, 2, 15, 53840], [0, 2, 4, 54560], [5, 1, 24, 55968], [0, 2, 12, 46496],
  [0, 2, 1, 22224], [2, 1, 22, 19160], [0, 2, 10, 18864], [7, 1, 30, 42168], [0, 2, 17, 42160], [0, 2, 6, 43600],
  [5, 1, 26, 46376], [0, 2, 14, 27936], [0, 2, 2, 44448], [3, 1, 23, 21936], [0, 2, 11, 37744], [8, 2, 1, 18808],
  [0, 2, 19, 18800], [0, 2, 8, 25776], [6, 1, 28, 27216], [0, 2, 15, 59984], [0, 2, 4, 27424], [4, 1, 24, 43872],
  [0, 2, 12, 43744], [0, 2, 2, 37600], [3, 1, 21, 51568], [0, 2, 9, 51552], [7, 1, 29, 54440], [0, 2, 17, 54432],
  [0, 2, 5, 55888], [5, 1, 26, 23208], [0, 2, 14, 22176], [0, 2, 3, 42704], [4, 1, 23, 21224], [0, 2, 11, 21200],
  [8, 1, 31, 43352], [0, 2, 19, 43344], [0, 2, 7, 46240], [6, 1, 27, 46416], [0, 2, 15, 44368], [0, 2, 5, 21920],
  [4, 1, 24, 42448], [0, 2, 12, 42416], [0, 2, 2, 21168], [3, 1, 22, 43320], [0, 2, 9, 26928], [7, 1, 29, 29336],
  [0, 2, 17, 27296], [0, 2, 6, 44368], [5, 1, 26, 19880], [0, 2, 14, 19296], [0, 2, 3, 42352], [4, 1, 24, 21104],
  [0, 2, 10, 53856], [8, 1, 30, 59696], [0, 2, 18, 54560], [0, 2, 7, 55968], [6, 1, 27, 27472], [0, 2, 15, 22224],
  [0, 2, 5, 19168], [4, 1, 25, 42216], [0, 2, 12, 42192], [0, 2, 1, 53584], [2, 1, 21, 55592], [0, 2, 9, 54560]
]

/**
 * 将阳历转换为阴历
 * @param year
 * @param month
 * @param date
 */
export const convertSolarToLunar = (year, month, date) => {
  let yearData = lunarInfo[year - MIN_YEAR]
  // if(year==this.MIN_YEAR && month<=2 && date<=9) return [1891,'正月','初一','辛卯',1,1,'兔'];
  return getLunarByBetween(year, getDaysBetweenSolar(year, month, date, yearData[1], yearData[2]))
}

/**
 * 将阳历月份转换为阴历
 * @param year
 * @param month
 * @param date
 */
export const convertSolarMonthToLunar = (year, month, date) => {
  let yearData = lunarInfo[year - MIN_YEAR]
  // if(year==MIN_YEAR && month<=2&&date<=9) return array(1891,'正月','初一','辛卯',1,1,'兔');
  let month_days_ary = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  let dd = month_days_ary[month]
  if (isLeapYear(year) && month == 2) dd++
  let lunar_ary = []
  for (var i = 1; i < dd; i++) {
    let array = getLunarByBetween(year, getDaysBetweenSolar(year, month, i, yearData[1], yearData[2]))
    array.push(year + '-' + month + '-' + i)
    lunar_ary[i] = array
  }
  return lunar_ary
}

/**
 * 将阴历转换为阳历
 * @param year
 * @param month
 * @param date
 */
export const convertLunarToSolar = (year, month, date) => {
  let yearData = lunarInfo[year - MIN_YEAR]
  let between = getDaysBetweenLunar(year, month, date)
  // hour minute second month day year
  // let res = mktime(0,0,0,yearData[1],yearData[2],year);
  let res = Date.parse(yearData[1] + ', ' + yearData[2] + ', ' + year)
  res = new Date(Number(res) + Number(between * 24 * 60 * 60 * 1000))
  let year1 = res.getFullYear()
  let month1 = parseInt(res.getMonth()) + parseInt(1)
  let day = res.getDate()
  return [year1, month1, day]
}

/**
 * 是否润年
 * @param year
 */
export const isLeapYear = (year) => {
  return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) ? true : false
}

/**
 * 获取干支纪年 该函数可能有问题
 * @param year
 */
const getLunarYearName = (year) => {
  let sky = ['庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己']
  let earth = ['申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未']
  year = year + ''
  return sky[year % 10] + earth[year % 12]
}

/**
 * 获取生肖
 * @param year
 */
const getYearZodiac = (year) => {

}

/**
 * 获取阳历月份的天数
 * @param year
 * @param month
 */
export const getSolarMonthDays = (year, month) => {
  let monthHash = [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  return monthHash[month - 1]
}

/**
 * 获取阴历月份的天数
 * @param year
 * @param month
 */
export const getLunarMonthDays = (year, month) => {
  let monthData = getLunarMonths(year)
  return monthData[month - 1]
}

/**
 * 获取阴历月份每月的天数的数组
 * @param year
 */
export const getLunarMonths = (year) => {
  let yearData = lunarInfo[year - MIN_YEAR]
  let leapMonth = yearData[0]
  let bit = yearData[3].toString(2)
  let bitArray = []
  for (var i = 0; i < bit.length; i++) bitArray[i] = bit.substr(i, 1)
  for (var k = 0, klen = 16 - bitArray.length; k < klen; k++) bitArray.splice(0, 0, 0)
  bitArray = bitArray.slice(0, (leapMonth == 0 ? 12 : 13)) //array_slice(bitArray,0,(leapMonth==0 ? 12 : 13));
  for (i = 0; i < bitArray.length; i++) bitArray[i] = parseInt(bitArray[i]) + parseInt(29)
  return bitArray
}

/**
 * 获取农历每年的天数
 * @param year
 */
export const getLunarYearDays = (year) => {
  // let yearData = lunarInfo[year-MIN_YEAR];
  let monthArray = getLunarYearMonths(year)
  let len = monthArray.length
  return (monthArray[len - 1] == 0 ? monthArray[len - 2] : monthArray[len - 1])
}

/**
 * 获取阴历年月
 * @param year
 */
export const getLunarYearMonths = (year) => {
  let monthData = getLunarMonths(year)
  let res = []
  let temp = 0
  let yearData = lunarInfo[year - MIN_YEAR]
  let len = yearData[0] == 0 ? 12 : 13
  for (var i = 0; i < len; i++) {
    temp = 0
    for (var j = 0; j <= i; j++) temp = parseInt(temp) + parseInt(monthData[j])
    res.push(temp)
  }
  return res
}

/**
 * 获取闰月
 * @param year
 */
export const getLeapMonth = (year) => {
  let yearData = lunarInfo[year - MIN_YEAR]
  return yearData[0]
}

/**
 * 计算阴历日期与正月初一相隔的天数
 * @param year
 * @param month
 * @param date
 */
export const getDaysBetweenLunar = (year, month, date) => {
  let yearMonth = getLunarMonths(year)
  let res = 0
  for (var i = 1; i < month; i++) {
    res = parseInt(res) + parseInt(yearMonth[i - 1])
  }
  res = parseInt(res) + parseInt(date) - parseInt(1)
  return res
}

/**
 * 计算2个阳历日期之间的天数
 * @param year
 * @param cmonth
 * @param cdate 阴历正月对应的阳历月份
 * @param dmonth 阴历初一对应的阳历天数
 * @param ddate
 */
export const getDaysBetweenSolar = (year, cmonth, cdate, dmonth, ddate) => {
  let a = Date.parse(cmonth + '/' + cdate + '/' + year)
  let b = Date.parse(dmonth + '/' + ddate + '/' + year)
  return Math.ceil((a - b) / 24 / 3600 / 1000)
}

/**
 * 根据距离正月初一的天数计算阴历日期
 * @param year
 * @param between
 */
export const getLunarByBetween = (year, between) => {
  let lunarArray = []
  let yearMonth = []
  let t = 0
  let e = 0
  let leapMonth = 0
  let m = ''
  if (between == 0) {
    lunarArray.push(year)
    lunarArray.push(1)
    lunarArray.push(1)
    t = 1
    e = 1
  } else {
    year = between > 0 ? year : (year - 1)
    yearMonth = getLunarYearMonths(year)
    leapMonth = getLeapMonth(year)
    between = between > 0 ? between : (Number(getLunarYearDays(year)) + Number(between))
    for (var i = 0; i < 13; i++) {

      if (between == yearMonth[i]) {
        t = parseInt(i) + parseInt(2)
        e = 1
        break
      } else if (between < yearMonth[i]) {
        t = parseInt(i) + parseInt(1)
        e = parseInt(between) - parseInt((yearMonth[i - 1] == null ? 0 : yearMonth[i - 1])) + parseInt(1)
        break
      }
    }
    m = leapMonth != 0 && t == (parseInt(leapMonth) + parseInt(1)) ? '闰' + (t - 1) :
      (leapMonth != 0 && (parseInt(leapMonth) + parseInt(1)) < t ? t - 1 : t)
    // console.log(t)
    lunarArray.push(year)
    lunarArray.push(m)
    lunarArray.push(e)
  }
  // lunarArray.push(t)
  // lunarArray.push(e)
  // lunarArray.push(leapMonth)

  // array_push(lunarArray,this->getLunarYearName(year));// 天干地支
  // array_push(lunarArray,t,e);
  // array_push(lunarArray,this->getYearZodiac(year));// 12生肖
  // array_push(lunarArray,leapMonth);// 闰几月
  return lunarArray
}

/**
 * 获取数字的阴历叫法
 * @param num 数字
 * @param isMonth 是否是月份的数字
 */
const getCapitalNum = (num, isMonth) => {

}

/**
 * 节气通用算法
 * @param year
 * @param month
 * @param day
 */
const getJieQi = (year, month, day) => {

}

/**
 * 获取节日：特殊的节日只能修改此函数来计算
 * @param today
 * @param nl_info
 * @param config
 */
const getFestival = (today, nl_info, config = 1) => {
  nl_info = nl_info === '' || nl_info === undefined ? false : nl_info
  config = config === '' || config === undefined ? 1 : config
}
